<!DOCTYPE html>
<html>
  <head>
    <!-- 贴图，有几个面，贴几个图 -->
    <!-- <script src="node_modules/three/build/three.js"></script> -->
    <script type="importmap">
      {
        "imports": {
          "three": "./node_modules/three/build/three.module.js",
          "three/addons/": "./node_modules/three/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from "three";

      // 引入dat.gui.js的一个类GUI
      import { GUI } from "three/addons/libs/lil-gui.module.min.js";
      import { OrbitControls } from "three/addons/controls/OrbitControls.js";

      // 浏览器控制台测试，是否引入成功
      console.log(THREE.Scene);
      console.log("完成");
      const width = window.innerWidth;
      const height = window.innerHeight;

      // 开始创建
      // 设置场景,坐标原点 0，0，0 中场景中央
      const scene = new THREE.Scene();

      // 点光源
      const pointLight = new THREE.PointLight(0xffffff, 1.0);
      scene.add(pointLight);
      pointLight.position.set(500, 500, 600);

      //纹理贴图加载器TextureLoader
      const texLoader = new THREE.TextureLoader();
      // .load()方法加载图像，返回一个纹理对象Texture
      const texture1 = texLoader.load("public/image/cizuan.png");
      const material1 = new THREE.MeshLambertMaterial({
        // 设置纹理贴图：Texture对象作为材质map属性的属性值
        map: texture1, //map表示材质的颜色贴图属性
      });

      // 地砖1
      const planeGeometry1 = new THREE.PlaneGeometry(100, 50);

      const planeMesh1 = new THREE.Mesh(planeGeometry1, material1);
      planeMesh1.position.set(-80, 0, 0);
      planeMesh1.name = "地砖1";
      planeMesh1.rotateX(-Math.PI / 2);
      scene.add(planeMesh1);

      // 地砖2
      const planeGeometry2 = new THREE.PlaneGeometry(100, 50);

      const texture2 = texLoader.load("public/image/cizuan.png");

      // 设置阵列模式
      texture2.wrapS = THREE.RepeatWrapping;
      texture2.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量， 4 列， 5 行，为什么先是列呢？因为列是在 X 轴上分
      texture2.repeat.set(4, 5); //注意选择合适的阵列数量

      const material2 = new THREE.MeshLambertMaterial({
        // 设置纹理贴图：Texture对象作为材质map属性的属性值
        map: texture2, //map表示材质的颜色贴图属性
      });

      const planeMesh2 = new THREE.Mesh(planeGeometry2, material2);
      planeMesh2.position.set(80, 0, 0);
      planeMesh2.name = "地砖2";

      planeMesh2.rotateX(-Math.PI / 2);

      scene.add(planeMesh2);

      // 添加一个辅助网格地面
      const gridHelper = new THREE.GridHelper(300, 30, 0x004444, 0x004444);
      scene.add(gridHelper);

      const camera = new THREE.PerspectiveCamera(50, width / height, 10, 1000);

      // 设置摄像机的位置
      camera.position.set(0, 60, 200);

      // 设置摄像机的观察点
      camera.lookAt(0, 20, 0);

      // 摄像机从 x -12 向 x 0 方向观察
      console.log(`camera`, camera.position);

      // 设置渲染器
      const renderer = new THREE.WebGLRenderer();

      renderer.setSize(width, height);

      // 设置空间背景颜色
      renderer.setClearColor(0xcccccc);
      renderer.render(scene, camera);

      document.body.appendChild(renderer.domElement);

      ///*
      const controls = new OrbitControls(camera, renderer.domElement);
      // 相机控件.target属性在OrbitControls.js内部表示相机目标观察点，默认0,0,0
      // console.log('controls.target', controls.target);
      controls.target.set(0, 20, 0);
      controls.update(); //update()函数内会执行camera.lookAt(controls.targe)

      //新版本，加载gltf，不需要执行下面代码解决颜色偏差
      //renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间
      //*/

      // 渲染方法
      function render() {
        // 用渲染器渲染
        renderer.render(scene, camera);

        // 重复渲染，需要查一下
        // 请求动画帧
        // requestAnimationFrame实现周期性循环执行
        // requestAnimationFrame默认每秒钟执行60次，但不一定能做到，要看代码的性能
        requestAnimationFrame(render); // 请求再次执行函数render, 放上面下面都行
        // 浏览器控制台查看相机位置变化
        //console.log('camera.position',camera.position);
        // 浏览器控制台查看controls.target变化，辅助设置lookAt参数
        //console.log('controls.target',controls.target);
      }

      // 执行渲染方法
      render();
    </script>
  </head>
  <body>
    GUI 控件
    <div id="monitor"></div>
  </body>
</html>
